package io.github.biezhi.elves.spider;

import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSON;
import io.github.biezhi.elves.model.CrawlTableHotel;
import io.github.biezhi.elves.model.HotelInfo;
import io.github.biezhi.elves.service.HotelService;
import io.github.biezhi.elves.utils.WebDriverUtils;
import lombok.extern.slf4j.Slf4j;

/**
 * 爬取百度拾取坐标系统网站信息数据入库类
 * 
 * 包括酒店/会所名称、地市、区域、地址、电话、坐标等数据信息
 *
 */
@Slf4j
@Service
public class HotelSpider {
	@Resource
	private HotelService hotelService;
	private static HotelService staticHotelService;
	
	@Bean
	public HotelService getHotelServiceBean(){
		if(hotelService!=null){
			staticHotelService = hotelService;
			return staticHotelService;
		}
		return null;
	}
	
	/**
	 * 开始执行爬虫百度拾取坐标系统操作
	 * @throws Exception 
	 */
	static final int pageNo = 1;
	static int pageSize = 20;
	public void startBaiduHotel() throws Exception{
		while(true){
//			pageNo++;
			baiduHotelPointData(pageNo, pageSize);
		}
	}
	
	/**
	 * 通过百度拾取坐标系统获取某酒店/会所坐标数据信息
	 * @param pageNo		参数说明:页号
     * @param pageSize		参数说明:每页显示记录数
	 */
	private void baiduHotelPointData(int pageNo, int pageSize) throws Exception{
		boolean isNull = false;
		List<HotelInfo> hotelInfoList = new ArrayList<HotelInfo>();
		List<CrawlTableHotel> existDataList = new ArrayList<CrawlTableHotel>();
		List<CrawlTableHotel> nullDataList = new ArrayList<CrawlTableHotel>();
		
		//查询还没爬取酒店会所列表数据
		int countDataNotIsLoad = hotelService.countCrawlTableHotelDataForNotLoad();
		if(countDataNotIsLoad==0){
			isNull = true;
		}
		//分页查询爬取酒店会所列表数据
		List<CrawlTableHotel> crawlTableHotelList = hotelService.queryCrawlTableHotelDataPage(pageNo, pageSize);
		if(isNull){
			if(crawlTableHotelList==null || crawlTableHotelList.size()==0){
				//分页查询爬取酒店会所为空列表数据
				crawlTableHotelList = hotelService.queryCrawlTableHotelIsNullDataPage(pageNo, pageSize);
			}
		}
		if(crawlTableHotelList!=null && crawlTableHotelList.size()>0){
			//当前要爬取数据不足最大记录数时,则取当前要爬取的数据量
			if(crawlTableHotelList.size()<pageSize){
				pageSize = crawlTableHotelList.size();
			}
			for(CrawlTableHotel crawlTableHotel : crawlTableHotelList){
				CrawlTableHotel existData = new CrawlTableHotel();
				CrawlTableHotel nullData = new CrawlTableHotel();
				HotelInfo hotelInfo = new HotelInfo();
				
				// 1、开启个浏览器并且输入链接
				WebDriver driver = WebDriverUtils.getChromeDriver("http://api.map.baidu.com/lbsapi/getpoint/index.html");

				String cityName = crawlTableHotel.getCity_name();
				String hotelName = crawlTableHotel.getHotel_name();
				String addrName = crawlTableHotel.getAddr_name();
				System.out.println("地市名称{{}}==>" + cityName + "搜素名称{{}}==>" + hotelName + "，地址详情{{}}==>" + addrName);
				
				// 2、向百度拾取坐标系统输入框输入需要查询的值
				WebDriverUtils.inputStrByJS(driver, "localvalue", hotelName);
				
				// 3、点击百度拾取坐标系统[更换城市]
				JavascriptExecutor js = (JavascriptExecutor) driver;
		        js.executeScript("showPop()");

		        // 休息5秒，加载数据
		 		try {
		 			Thread.sleep(5000);
		 		} catch (InterruptedException e) {
		 			e.printStackTrace();
		 		}
		 		
		 		// 4、修改百度拾取坐标系统[更换城市]的值
		 		//广州
				if("广州".equals(cityName)){
			 		WebElement changeCityElement = driver.findElement(By.xpath("//*[@id=\"selCity\"]/tbody/tr[6]/td[2]/nobr[1]/a"));
			 		WebDriverUtils.scrollToElementAndClick(changeCityElement, driver);
				}else if("深圳".equals(cityName)){
					//深圳
					WebElement changeCityElement = driver.findElement(By.xpath("//*[@id=\"selCity\"]/tbody/tr[6]/td[2]/nobr[15]/a"));
			 		WebDriverUtils.scrollToElementAndClick(changeCityElement, driver);
				}
				
				 // 休息5秒，加载数据
		 		try {
		 			Thread.sleep(5000);
		 		} catch (InterruptedException e) {
		 			e.printStackTrace();
		 		}
		 		
				// 5、得到百度一下的按钮
				WebElement submitElement = driver.findElement(By.id("localsearch"));
		
				// 6、点击百度一下
				WebDriverUtils.scrollToElementAndClick(submitElement, driver);
		
				// 休息5秒，加载数据
				try {
					Thread.sleep(5000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				
				hotelInfo.setCityName(crawlTableHotel.getCity_name());
				hotelInfo.setAreaName(crawlTableHotel.getArea_name());
				hotelInfo.setHotelName(hotelName);
				hotelInfo.setAddrName(crawlTableHotel.getAddr_name());
				// 7、右侧地图Info中div的 id 为 MapInfo 的 div 下面的所有 div
				List<WebElement> divElements = driver.findElements(By.cssSelector("#MapInfo > #txtPanel > ul"));
				
				if(divElements!=null && divElements.size()>0){
					for(int i = 0; i<divElements.size(); i++){
						// 8、找到搜索的第一个链接
						try{
							WebElement aElement = divElements.get(i).findElement(By.cssSelector("li > div > a"));
							if(aElement!=null){
								String textName = aElement.getText();
								if(textName.equals(crawlTableHotel.getHotel_name())){
									System.out.println("hotelName{{}}==>" + hotelName);
									hotelInfo.setHotelName(textName);
									existData.setHotel_name(textName);
									existDataList.add(existData);
								}else{
									System.out.println("textName{{}}==>" + textName);
									hotelInfo.setHotelName(hotelName);
									hotelInfo.setBaiduHotelName(textName);
									
									if(isNull){
										existData.setHotel_name(hotelName);
										existDataList.add(existData);
									}else{
										nullData.setHotel_name(hotelName);
										nullDataList.add(nullData);
										continue;
									}
								}
							}else{
								System.err.println("没有匹配到数据!!!");
							}
						}catch(Exception e){
							System.err.println("aElement进入catch异常,没有匹配到数据,把酒店/会所名称【" + hotelName + "】放到nullDataList集合里面去{{}}==>");
							String resultCont = driver.findElement(By.cssSelector("#MapInfo > #txtPanel")).getText();
							System.err.println(resultCont);
							hotelInfo.setResultCont(resultCont);
							if(isNull){
								existData.setHotel_name(hotelName);
								existDataList.add(existData);
							}else{
								nullData.setHotel_name(hotelName);
								nullDataList.add(nullData);
							}
						}
						
						try{
							WebElement pElement = divElements.get(i).findElement(By.cssSelector("li > div > p"));
							if(pElement!=null){
								String splitStr1 = "：";
								String splitStr2 = ",";
								String pTextName = pElement.getText();
								String[] pTexts = pElement.getText().split("\n");
//								System.out.println(pTextName);
								
								if(pTextName.contains("电话" + splitStr1)){
									hotelInfo.setTelephone(pTexts[1].split(splitStr1)[1]);
									hotelInfo.setPointX(pTexts[2].split(splitStr1)[1].split(splitStr2)[0]);
									hotelInfo.setPointY(pTexts[2].split(splitStr1)[1].split(splitStr2)[1]);
									System.out.println("电话号码{{}}==>" + pTexts[1].split(splitStr1)[1]);
									System.out.println("横坐标{{}}==>" + pTexts[2].split(splitStr1)[1].split(splitStr2)[0]);
									System.out.println("纵坐标{{}}==>" + pTexts[2].split(splitStr1)[1].split(splitStr2)[1]);
								}else{
									hotelInfo.setPointX(pTexts[1].split(splitStr1)[1].split(splitStr2)[0]);
									hotelInfo.setPointY(pTexts[1].split(splitStr1)[1].split(splitStr2)[1]);
									System.out.println("横坐标{{}}==>" + pTexts[1].split(splitStr1)[1].split(splitStr2)[0]);
									System.out.println("纵坐标{{}}==>" + pTexts[1].split(splitStr1)[1].split(splitStr2)[1]);
								}
								break;
							}else{
								System.err.println("没有匹配到数据!!!");
							}
						}catch(Exception e){
							System.err.println("pElement进入catch异常,没有匹配到数据!!!");
						}
					}
				}else{
					String resultCont = driver.findElement(By.cssSelector("#MapInfo > #txtPanel")).getText();
					System.err.println(resultCont);
					hotelInfo.setResultCont(resultCont);
					
					if(isNull){
						existData.setHotel_name(hotelName);
						existDataList.add(existData);
					}else{
						nullData.setHotel_name(hotelName);
						nullDataList.add(nullData);
					}
				}
				hotelInfoList.add(hotelInfo);
				
				if(hotelInfoList!=null && hotelInfoList.size()>0){
					String jsonStr = JSON.toJSONString(hotelInfoList);
					System.out.println(jsonStr);
				}
				
				int total = 0;
				int existDataListSize = 0;
				int nullDataListSize = 0;
				if(existDataList!=null && existDataList.size()>0){
					existDataListSize = existDataList.size();
				}
				if(nullDataList!=null && nullDataList.size()>0){
					nullDataListSize = nullDataList.size();
				}
				total = existDataListSize + nullDataListSize;
				System.out.println("total{{}}==>" + total);
				System.out.println("existDataListSize{{}}==>" + existDataListSize);
				System.out.println("nullDataListSize{{}}==>" + nullDataListSize);
				System.out.println("现爬取量为:" + total + "，最大可爬取量为:" + pageSize);
				if(total==pageSize){
					boolean isSave = false;
					if(existDataList!=null && existDataList.size()>0){
						//根据酒店/会所名称批量更新爬取列表数据表设置is_load字段为T(意指在百度拾取坐标系统网站搜索到坐标数据并入库)
						hotelService.batchUpdateCrawlTableHotelDataForIsLoad(existDataList);
						isSave = true;
					}
					if(nullDataList!=null && nullDataList.size()>0){
						//根据酒店/会所名称批量更新爬取列表数据表设置is_null字段为T(意指在百度拾取坐标系统网站没有搜索到坐标数据)
						hotelService.batchUpdateCrawlTableHotelDataForIsNull(nullDataList);
						isSave = true;
					}
					if(isSave && hotelInfoList!=null && hotelInfoList.size()>0){
						//批量保存酒店/会所数据
						hotelService.batchSaveHotelInfo(hotelInfoList);
					}
				}
				
				System.out.println("休眠8000毫秒......");
				try{
					Thread.sleep(8000);
				}catch(Exception e){
				}
				System.out.println("已休眠8000毫秒,继续查询数据==>");
				driver.quit();
			}
		}else{
			System.out.println("要爬取酒店/会所数据为空，系统自动停止!!!");
			System.exit(0);;
		}
	}
	
	/**
	 * 通过百度拾取坐标系统获取某酒店/会所坐标数据信息
	 */
	private static void testBaiduHotelPointData(){
		String cityName = "深圳";
		String hotelName = "香格里拉大酒店CHI水疗";
		// 1、开启个浏览器并且输入链接
		WebDriver driver = WebDriverUtils.getChromeDriver("http://api.map.baidu.com/lbsapi/getpoint/index.html");
		System.out.println("搜素名称{{}}==>" + hotelName);
		
		// 2、向百度拾取坐标系统输入框输入需要查询的值
		WebDriverUtils.inputStrByJS(driver, "localvalue", hotelName);
		
		JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("showPop()");

        // 休息5秒，加载数据
 		try {
 			Thread.sleep(5000);
 		} catch (InterruptedException e) {
 			e.printStackTrace();
 		}
 		
 		if("广州".equals(cityName)){
 			//广州
 			WebElement changeCityElement = driver.findElement(By.xpath("//*[@id=\"selCity\"]/tbody/tr[6]/td[2]/nobr[1]/a"));
 			WebDriverUtils.scrollToElementAndClick(changeCityElement, driver);
 		}else if("深圳".equals(cityName)){
	 		//深圳
 			WebElement changeCityElement = driver.findElement(By.xpath("//*[@id=\"selCity\"]/tbody/tr[6]/td[2]/nobr[15]/a"));
	 		WebDriverUtils.scrollToElementAndClick(changeCityElement, driver);
 		}

        // 休息5秒，加载数据
 		try {
 			Thread.sleep(5000);
 		} catch (InterruptedException e) {
 			e.printStackTrace();
 		}
		
		// 4、得到百度一下的按钮
		WebElement submitElement = driver.findElement(By.id("localsearch"));

		// 5、点击百度一下
		WebDriverUtils.scrollToElementAndClick(submitElement, driver);

		// 休息5秒，加载数据
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		// 6、右侧地图Info中div的 id 为 MapInfo 的 div 下面的所有 div
		List<WebElement> divElements = driver.findElements(By.cssSelector("#MapInfo > #txtPanel > ul"));
		
		if(divElements!=null && divElements.size()>0){
			for(int i = 0; i<divElements.size(); i++){
				// 7、找到搜索的第一个链接
				try{
					WebElement aElement = divElements.get(i).findElement(By.cssSelector("li > div > a"));
					String aTextName = aElement.getText();
					if(aElement!=null){
						if(aTextName.equals(hotelName)){
							System.out.println("hotelName{{}}==>" + hotelName);
						}else{
							System.out.println("aTextName{{}}==>" + aTextName);
						}
					}else{
						System.err.println("没有匹配到数据!!!");
					}
					WebElement pElement = divElements.get(i).findElement(By.cssSelector("li > div > p"));
					if(pElement!=null){
						String splitStr1 = "：";
						String splitStr2 = ",";
						String pTextName = pElement.getText();
						String[] pTexts = pElement.getText().split("\n");
//						System.out.println(pTextName);
						
						if(pTextName.contains("电话" + splitStr1)){
							System.out.println("电话号码{{}}==>" + pTexts[1].split(splitStr1)[1]);
							System.out.println("横坐标{{}}==>" + pTexts[2].split(splitStr1)[1].split(splitStr2)[0]);
							System.out.println("纵坐标{{}}==>" + pTexts[2].split(splitStr1)[1].split(splitStr2)[1]);
						}else{
							System.out.println("横坐标{{}}==>" + pTexts[1].split(splitStr1)[1].split(splitStr2)[0]);
							System.out.println("纵坐标{{}}==>" + pTexts[1].split(splitStr1)[1].split(splitStr2)[1]);
						}
					}else{
						System.err.println("没有匹配到数据!!!");
					}
				}catch(Exception e){
					System.err.println("进入catch异常,没有匹配到数据!!!");
				}
			}
		}else{
			System.err.println(driver.findElement(By.cssSelector("#MapInfo > #txtPanel")).getText());
		}
		driver.quit();
	}
	
	public static void main(String[] args){
		testBaiduHotelPointData();
	}
}